﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.AddIn;
using RootfusAddinView;
using System.IO;
using ROOTNET.Interface;

namespace MacroLoaderAddin.MacroAddIn
{
    /// <summary>
    /// An addin that will do division of two histograms.
    /// </summary>
    [AddIn("Load a ROOT Macro", Description = "Loads a ROOT macro .C file and interprets it. Should have global effects.")]
    public class MacroAddIn : RootfusSurfaceItem
    {
        /// <summary>
        /// Deafult dtor.
        /// </summary>
        public MacroAddIn()
        {
        }

        /// <summary>
        /// Cache the local copy of the user interface. Best to
        /// reference SurfaceUI property as that will make sure
        /// it is created.
        /// </summary>
        private MacroAddInUINormal _ui_norm = null;

        /// <summary>
        /// Returns the normal UI. Only create one per addin instance! If you get asked
        /// for it multiple times return the same one!
        /// </summary>
        public override System.Windows.FrameworkElement SurfaceUI
        {
            get
            {
                if (_ui_norm == null)
                {
                    _ui_norm = new MacroAddInUINormal();
                }
                return _ui_norm;
            }
        }

        /// <summary>
        /// Return the config UI. Return a new one each time, or keep
        /// track -- whatever is simpler.
        /// </summary>
        public override System.Windows.FrameworkElement ConfigUI
        {
            get {
                MacroAddInUIConfig cfg = new MacroAddInUIConfig(this);
                cfg.DataContext = this;
                CacheState();
                return cfg;
            }
        }

        /// <summary>
        /// If you don't need a config -- then get rid fo the ConfigUI and change the
        /// return to false.
        /// </summary>
        public override bool HasSettingsUI
        {
            get { return true; }
        }

        #region Settings

        /// <summary>
        /// Get/Set the filename of the guy that we are going to load.
        /// </summary>
        public string MacroFilename { get; set; }

        /// <summary>
        /// Maintains the state
        /// </summary>
        public class MacroState
        {
            public string _fname;
        }

        private MacroState _cached_state = new MacroState();

        /// <summary>
        /// Save the cached state.
        /// </summary>
        private void CacheState()
        {
            _cached_state._fname = MacroFilename;
        }

        /// <summary>
        /// Return true if the settings are now different!
        /// </summary>
        /// <returns></returns>
        private bool IsDifferentFromCachedState()
        {
            return _cached_state._fname != MacroFilename;
        }

        /// <summary>
        /// User has (perhaps) changed our config. If so, deal with it!
        /// </summary>
        public override void ConfigDone()
        {
            if (IsDifferentFromCachedState())
            {
                CacheState();
                Callback.UpdateSaveObject(_cached_state);
                Update();
            }
        }

        /// <summary>
        /// The settings are being... set. We should load them!
        /// </summary>
        /// <param name="xml_config"></param>
        public override void SetConfigXML(string xml_config)
        {
            MacroState st = Callback.ConvertXMLToSettings<MacroState>(xml_config);
            MacroFilename = st._fname;
            Update();
        }

        #endregion

        /// <summary>
        /// We have no input or output pins...
        /// </summary>
        private List<PinDefinition> _input_pins = new List<PinDefinition>();
        private List<string> _output_pins = new List<string>();

        /// <summary>
        /// What are our input pins? Make some custom ones based on
        /// PinDefinition as your parent class. It is normal to create this
        /// list just once.
        /// </summary>
        public override IList<PinDefinition> InputPins
        {
            get { return _input_pins; }
        }

        /// <summary>
        /// What are our output pins? Similar to before. It is normal
        /// to create a list once.
        /// </summary>
        public override IList<string> OutputPinNames
        {
            get { return _output_pins; }
        }

        /// <summary>
        /// This addin has no inputs or outputs, but we should
        /// load a macro. Note we can't "unload" a macro... so...
        /// </summary>
        public override void Update()
        {
            ///
            /// Get the UI correct
            /// 

            string filestub = MacroFilename;
            if (filestub.IndexOf("\\") >= 0)
            {
                filestub = filestub.Substring(filestub.LastIndexOf("\\") + 1);
            }
            if (filestub.IndexOf(".") >= 0)
            {
                filestub = filestub.Substring(0, filestub.LastIndexOf("."));
            }
            (SurfaceUI as MacroAddInUINormal).filenameLabel.Content = filestub;

            ///
            /// Next, load in the file. If possible. :-)
            /// 

            if (File.Exists(MacroFilename))
            {
                int result = ROOTNET.NTInterpreter.Instance().ExecuteMacro(MacroFilename);
                NTStyle style = ROOTNET.NTROOT.gROOT.GetStyle("ATLAS");
                string sname = ROOTNET.NTStyle.gStyle.GetName();
            }
        }
    }
}
